<template>
  <Drawer
    :closable="false"
    :destroyOnClose="true"
    :title="
      drawerType === 0
        ? '新增后端升级任务'
        : drawerType === 2
        ? '新增前端升级任务'
        : drawerType === 3
        ? '编辑前端升级任务'
        : '编辑后端升级任务'
    "
    :visible="visible"
    :width="1000"
    @close="handleCancel"
  >
    <template #footer>
      <a-space class="float-right">
        <Button class="mr-10px" @click="handleCancel">取消</Button>
        <Button type="primary" @click="handleSubmit">提交</Button>
      </a-space>
    </template>
    <Form ref="formRef" :model="form" :rules="rules" labelAlign="right" layout="vertical">
      <Divider>基本信息</Divider>
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="升级任务" name="name">
            <Input
              v-model:value="form.name"
              :disabled="drawerType === 1 || drawerType === 3"
              placeholder="请输入任务名称"
            />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem v-if="drawerType !== 1 && drawerType !== 3" label="应用" name="appId">
            <Select
              v-model:value="form.appId"
              :disabled="drawerType === 1"
              :field-names="{ label: 'name', value: 'id' }"
              :options="appSelectList"
              placeholder="请选择应用"
              @select="handleAppChange"
            />
          </FormItem>
          <FormItem v-if="drawerType === 1 || drawerType === 3" label="应用" name="app">
            <Input v-model:value="form.app" :disabled="drawerType === 1 || drawerType === 3" />
          </FormItem>
        </Col>
      </Row>
      <Row :gutter="16">
        <Col :span="12">
          <FormItem v-if="drawerType !== 1" label="企业名称" name="tenantCode">
            <Select
              v-model:value="form.tenantCode"
              :disabled="drawerType === 1 ? true : !form.appId"
              :field-names="{ label: 'name', value: 'code' }"
              :options="tenantSelectList"
              placeholder="请选择企业"
              @select="handleTenantChange"
            />
          </FormItem>
          <FormItem v-if="drawerType === 1" label="企业名称" name="tenantCode">
            <Input v-model:value="form.tenant" :disabled="true" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem v-if="drawerType !== 1" label="组件" name="componentId">
            <Select
              v-model:value="form.componentId"
              :disabled="drawerType === 1 ? true : !form.appId"
              :field-names="{ label: 'name', value: 'id' }"
              :options="componentSelectList"
              placeholder="请选组件"
              @change="handleComponentChange"
            />
          </FormItem>
          <FormItem v-if="drawerType === 1" label="组件" name="componentId">
            <Input v-model:value="form.component" :disabled="true" />
          </FormItem>
        </Col>
      </Row>
      <Row v-if="drawerType !== 2" :gutter="16">
        <Col :span="12">
          <FormItem v-if="drawerType !== 1" label="套餐类型" name="packageId">
            <Select
              v-model:value="form.packageId"
              :disabled="drawerType === 1 ? true : !form.tenantCode"
              :field-names="{ label: 'type', value: 'id' }"
              :options="instanceSelectList"
              placeholder="请选择套餐类型"
            />
          </FormItem>
          <FormItem v-if="drawerType === 1" label="套餐类型" name="packageId">
            <Input v-model:value="form.instance" :disabled="true" />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="任务描述" name="description">
            <Textarea v-model:value="form.description" :maxlength="6" :rows="2" placeholder="请输入任务描述" />
          </FormItem>
        </Col>
      </Row>
      <Row v-if="drawerType === 2" :gutter="16">
        <Col :span="12">
          <FormItem label="任务描述" name="description">
            <Textarea v-model:value="form.description" :maxlength="6" :rows="2" placeholder="请输入任务描述" />
          </FormItem>
        </Col>
      </Row>
      <Divider>升级信息</Divider>
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="命名空间" name="cceNamespace">
            <Input
              v-model:value="form.cceNamespace"
              :disabled="drawerType === 1 ? true : !form.componentId"
              placeholder="请输入命名空间"
            />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="工作负载" name="previousCceDeployment">
            <Input
              v-model:value="form.previousCceDeployment"
              :disabled="drawerType === 1 ? true : !form.componentId"
              placeholder="请输入工作负载"
            />
          </FormItem>
        </Col>
      </Row>
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="升级前版本" name="previousVersion">
            <Input
              v-model:value="form.previousVersion"
              :disabled="drawerType === 1 ? true : !form.componentId"
              placeholder="请输入升级前版本"
            />
          </FormItem>
        </Col>
        <Col :span="12">
          <FormItem label="升级后版本" name="currentVersion">
            <Select
              v-model:value="form.currentVersion"
              :disabled="drawerType === 1 ? true : !form.componentId"
              :field-names="{ label: 'componentVersion', value: 'componentVersion' }"
              :options="imagesSelectList"
              placeholder="请选择即将升级的微服务版本"
              @change="handleImagesChange"
            />
          </FormItem>
        </Col>
      </Row>
      <Row :gutter="16">
        <Col :span="24">
          <FormItem label="升级后镜像" name="currentImage">
            <Input v-model:value="form.currentImage" :disabled="true" placeholder="请输入升级后镜像" />
          </FormItem>
        </Col>
      </Row>
      <Divider>升级方式</Divider>
      <Row :gutter="16">
        <Col :span="12">
          <FormItem label="升级方式" name="type">
            <Select
              ref="select"
              v-model:value="form.type"
              :disabled="drawerType === 1"
              :options="upgradType"
              placeholder="请输选择升级方式"
            />
          </FormItem>
        </Col>
        <template v-if="form.type === 'BLUEGREEN'">
          <Col :span="12">
            <FormItem label="新版本权重" name="weight">
              <!-- <Input v-model:value="form.weight" style="display: flex" /> -->
              <RadioGroup v-model:value="form.weight" size="middle">
                <RadioButton value="0">0</RadioButton>
                <RadioButton value="100">100</RadioButton>
              </RadioGroup>
            </FormItem>
          </Col>
        </template>
      </Row>
      <template v-if="form.type === 'ROLLING'">
        <Row :gutter="16">
          <Col :span="12">
            <FormItem label="maxUnavailable" name="maxUnavailable">
              <Input v-model:value="form.maxUnavailable" style="display: flex" />
            </FormItem>
          </Col>
          <Col :span="12">
            <FormItem label="maxSurge" name="maxSurge">
              <Input v-model:value="form.maxSurge" style="display: flex" />
            </FormItem>
          </Col>
        </Row>
      </template>
    </Form>
    <template v-if="form.type === 'GRAY'">
      <Divider />
      <Button class="editable-add-btn" style="margin-bottom: 8px" @click="handleAdd">添加参数 </Button>
      <Table :columns="grayParamColumns" :dataSource="headerDataSource" :pagination="false" bordered>
        <template #bodyCell="{ column, record, index }">
          <template v-if="column.key === 'headersField'">
            <Select v-model:value="headerDataSource[index].headersField" :allowClear="true" style="display: flex">
              <SelectOption value="tenant">tenant</SelectOption>
              <SelectOption value="userid">userid</SelectOption>
              <SelectOption value="appid">appid</SelectOption>
            </Select>
          </template>
          <template v-if="column.key === 'type'">
            <Select v-model:value="headerDataSource[index].type" :allowClear="true" style="display: flex">
              <SelectOption value="regex">正则匹配</SelectOption>
              <SelectOption value="exact">精确匹配</SelectOption>
            </Select>
          </template>
          <template v-if="column.key === 'pattern'">
            <Input v-model:value="headerDataSource[index].pattern" style="display: flex" />
          </template>
          <template v-if="column.key === 'weight'">
            <Input v-model:value="headerDataSource[index].weight" style="display: flex" />
          </template>
          <template v-if="column.key === 'precedence'">
            <Input v-model:value="headerDataSource[index].precedence" style="display: flex" />
          </template>
          <template v-if="column.key === 'operation'">
            <Popconfirm v-if="headerDataSource.length" title="确定要删除吗?" @confirm="onDelete(record.key)">
              <a>删除</a>
            </Popconfirm>
          </template>
        </template>
      </Table>
    </template>
  </Drawer>
</template>

<script lang="ts" setup>
import { computed, Ref, ref, watch } from 'vue';
import {
  Button,
  Col,
  Divider,
  Drawer,
  Form,
  FormItem,
  Input,
  message,
  Popconfirm,
  Row,
  Select,
  SelectOption,
  Table,
  Textarea,
  RadioGroup,
  RadioButton,
} from 'ant-design-vue';
import { createUpgradeTasks, editUpgradeTask, viewUpgradeTasks } from '/@/api/upgrade-center/upgradeTask';
import { grayParamColumns } from '../drawer.data';
import { GrayParamItem, UpgradeTaskCreateItem } from '/@/api/upgrade-center/model/upgradeTaskModel';
import {
  AppItem,
  CceInfo,
  ComponentItem,
  ImageItem,
  InstanceItem,
  TenantItem,
} from '/@/api/upgrade-center/model/upgradeFormModel';
import {
  getAppForTenants,
  getCceInfoByMetaInfo,
  getComponentListByApp,
  getImageListByComp,
  getInstanceListByAppTenant,
  getTenantListByApp,
} from '/@/api/upgrade-center/upgradeForm';
import lodash from 'lodash';
import { Rule } from 'ant-design-vue/es/form';

const rules: Record<string, Rule[]> = {
  name: [{ required: true, message: 'Please enter name' }],
  appId: [{ required: true, message: 'please select an appId' }],
  app: [{ required: true, message: 'please select an app' }],
  tenantCode: [{ required: true, message: 'Please select an tenantCode' }],
  packageId: [{ required: true, message: 'Please select an packageId' }],
  componentId: [{ required: true, message: 'please select componentId' }],
  cceNamespace: [{ required: true, message: 'Please enter cceNamespace' }],
  previousCceDeployment: [{ required: true, message: 'Please select an previousCceDeployment' }],
  previousVersion: [{ required: true, message: 'Please select an previousVersion' }],
  currentVersion: [{ required: true, message: 'Please select an currentVersion' }],
  currentImage: [{ required: true, message: 'Please select an currentImage' }],
  type: [{ required: true, message: 'Please select an type' }],
  weight: [{ required: true, message: 'Please enter weight' }],
  maxUnavailable: [{ required: true, message: 'Please enter maxUnavailable' }],
  maxSurge: [{ required: true, message: 'Please enter maxSurge' }],
};
const visible = ref(false);
const drawerType = ref(0);
// 灰度参数table
let headerDataSource: Ref<GrayParamItem[]> = ref([]);
const count = computed(() => headerDataSource.value.length + 1);
const handleAdd = () => {
  const header = {
    key: `${count.value}`,
    headersField: '',
    type: '',
    pattern: '',
    weight: 0,
    precedence: 0,
  };
  headerDataSource.value.push(header);
};
const onDelete = (key: string) => {
  headerDataSource.value = headerDataSource.value.filter((item) => item.key !== key);
};
const form = ref<Partial<UpgradeTaskCreateItem>>({});
const formRef = ref();
// 企业列表下拉选择器的function
let tenantSelectList = ref<TenantItem[]>([]);
// 套餐类型下拉选择器的function
let instanceSelectList = ref<InstanceItem[]>([]);
// 组件下拉选择器的function
let componentSelectList = ref<ComponentItem[]>([]);

const emits = defineEmits(['refresh']);
const handleCancel = function () {
  formRef.value.resetFields();
  headerDataSource.value = [];
  visible.value = false;
  emits('refresh');
};
const handleValidate = async () => {
  return formRef.value.validate();
};

// 应用下拉选择器的function
let appSelectList = ref<AppItem[]>([]);

async function getAppSelectList() {
  let res = await getAppForTenants();
  appSelectList.value = res;
}

async function handleAppChange() {
  let res = await getTenantListByApp({
    appId: String(form.value.appId),
  });
  tenantSelectList.value = res;

  let param = {
    appId: form.value.appId,
    requestType: 1,
  };
  if (drawerType.value === 2) {
    param = { appId: form.value.appId, requestType: 2 };
  }
  let resComponentList = await getComponentListByApp(param);
  componentSelectList.value = resComponentList;
}

async function handleTenantChange() {
  instanceSelectList.value = [];
  if (form.value.appId && form.value.tenantCode) {
    let res = await getInstanceListByAppTenant({
      appId: String(form.value.appId),
      tenantCode: String(form.value.tenantCode),
    });
    instanceSelectList.value = res;
  }
}

// 处理升级信息
// 升级后服务版本下拉选择器的function
let imagesSelectList = ref<ImageItem[]>([]);

async function handleComponentChange() {
  if (form.value.appId && form.value.tenantCode && form.value.componentId) {
    let cceInfo: CceInfo = await getCceInfoByMetaInfo({
      appId: form.value.appId,
      tenantCode: form.value.tenantCode,
      packageId: form.value.packageId,
      componentId: form.value.componentId,
    });
    let res = await getImageListByComp({
      appId: form.value.appId,
      componentId: form.value.componentId,
    });
    imagesSelectList.value = res;

    if (cceInfo) {
      form.value.cceNamespace = cceInfo.namespace;
      form.value.previousCceDeployment = cceInfo.currentDeployment;
      form.value.previousImageId = cceInfo.currentImageId;
      form.value.previousVersion = cceInfo.currentVersion;
    }
  }
}

// 选择升级后服务版本后触发的function
function handleImagesChange() {
  if (form.value.currentVersion) {
    const res = imagesSelectList.value.filter((img) => img.componentVersion === form.value.currentVersion).pop();
    form.value.currentImage = res.image;
    form.value.currentImageId = res.id;
  }
}

let upgradType = ref<any[]>([]);
// 升级方式
const serverUpgradType = ref([
  { label: '灰度升级', value: 'GRAY' },
  { label: '滚动升级', value: 'ROLLING' },
  { label: '替换升级', value: 'RECREATE' },
  { label: '蓝绿升级', value: 'BLUEGREEN' },
]);
const uiUpgradType = ref([{ label: '灰度升级', value: 'GRAY' }]);

async function getUpgradeTasks(id: any) {
  form.value = await viewUpgradeTasks({
    taskId: id,
  });
}

function openDrawer(param: number, args: Recordable) {
  drawerType.value = param;
  if (drawerType.value === 2) {
    upgradType.value = uiUpgradType.value;
  } else if (drawerType.value === 0) {
    upgradType.value = serverUpgradType.value;
  } else if (drawerType.value === 1 || drawerType.value === 3) {
    getUpgradeTasks(args.id).catch((e) => {
      return message.error(e.message);
    });
  }
  visible.value = true;
}

const handleSubmit = () => {
  if (drawerType.value === 1) {
    let param = {
      id: form.value.id,
      name: form.value.name,
      description: form.value.description,
      type: form.value.type,
      maxUnavailable: form.value.maxUnavailable,
      maxSurge: form.value.maxSurge,
      grayParamDtoList: form.value.grayParamDtoList,
    };
    let editParam = lodash.pickBy(param, (item) => item);
    editUpgradeTask(editParam);
  } else {
    if (form.value.type === 'GRAY') {
      form.value.grayParamDtoList = headerDataSource.value;
    }
    handleValidate().then(async () => {
      // 过滤参数中空值
      let par = lodash.pickBy(form.value, (item) => item);
      await createUpgradeTasks(par)
        .then(() => {
          message.success('创建升级任务成功！');
        })
        .catch((e) => {
          message.error('创建升级任务失败：' + e);
        });
      handleCancel();
    });
  }
};
watch(
  () => form.value.type,
  () => {
    form.value.weight = null;
    form.value.maxUnavailable = null;
    form.value.maxSurge = null;
    headerDataSource.value = [];
    form.value.grayParamDtoList = null;
  }
);
defineExpose({ openDrawer });
getAppSelectList();
</script>
